<html>
<head>
<title>CpcPaChi - Version 0.14</title>
<style type="text/css">
span {
	font-family: 'Courier New';
	font-size: 10pt;
	color: #000000;
}
.sc0 {
	color: #808080;
}
.sc3 {
	color: #008080;
}
.sc4 {
	color: #FF8000;
}
.sc5 {
	font-weight: bold;
	color: #0000FF;
}
.sc7 {
	color: #808080;
}
.sc9 {
	color: #804000;
}
.sc10 {
	font-weight: bold;
	color: #000080;
}
.sc11 {
}
</style>
</head>
<body>
<h2>Un compilador sencillo paso a paso (14 - Acercamiento a los procedimientos)</h2>

<p align="right">(Volver al <a href="doc.html">&iacute;ndice</a>) </p>

<p>En los lenguajes estructurados como Pascal se pueden definir procedimientos,
que &quot;encapsulan&quot; una serie de pasos, y funciones, que adem&aacute;s devuelven
un valor. Nuestro compilador a&uacute;n tiene muchas carencias 
(no se pueden declarar dos variables a la vez, no existen distintos tipos
de datos, faltan muchas &oacute;rdenes por incluir...)
y m&aacute;s de un
error (por ejemplo, no es capaz de reconocer operadores formados
por dos s&iacute;mbolos, como &lt;=), pero aun as&iacute; vamos a acercarnos
un poco a c&oacute;mo se podr&iacute;a generar el c&oacute;digo para los procedimientos,
y en el pr&oacute;ximo paso ser&aacute; cuando vayamos limando asperezas para
que nuestro compilador, adem&aacute;s de hacer un poco de todo, funcione un poco mejor...</p>

<p>En una primera toma de contacto, queremos que nuestro compilador
sea capaz de generar el c&oacute;digo para procedimientos muy b&aacute;sicos:
sin par&aacute;metros y sin variables locales (y, al no tratarse
de funciones, tampoco devolver&aacute;n ning&uacute;n valor).</p>

<p>Pretendemos que sea capaz de traducir correctamente fragmentos como</p>

<pre><code>procedure inicializa;
begin
  cpcMode(1);
  paper(0);
end;</code></pre>

<p>Que luego se usar&iacute;an desde el cuerpo del programa:</p>

<pre><code>begin
  inicializa;
  locate(10,3);
  ...</code></pre>

<p>Esto supone una serie de problemas:</p>
<ul>
  <li>El primer c&oacute;digo que encontramos al analizar el programa no ser&aacute; siempre realmente el cuerpo del programa, sino que puede tratarse de un procedimiento que ser&aacute; llamado m&aacute;s adelante... o quiz&aacute; incluso nunca, </li>
  <li>Cada procedimiento podr&aacute; ser llamado desde el cuerpo del programa o desde otro procedimiento, y cuando termine su ejecuci&oacute;n deber&aacute; volver al punto siguiente del cuerpo del programa (o del otro procedimiento). </li>
</ul>
Podemos intentar resolverlo as&iacute;::
<ul>
  <li>Podr&iacute;amos incluir el c&oacute;digo de los procedimientos 
al final, despu&eacute;s del c&oacute;digo del cuerpo del programa, 
pero si queremos hacer todo el an&aacute;lisis en una pasada no es la 
mejor soluci&oacute;n. La alternativa para poder ir convirtiendo a 
medida que se va leyendo es generar el c&oacute;digo de los 
procedimientos seg&uacute;n se encuentren, es decir, antes del 
programa. Por eso, como es posible que lo primero que encontremos no 
sea lo primero que debemos ejecutar, el programa deber&iacute;a 
comenzar con un salto al comienzo del cuerpo (que a&uacute;n no 
sabemos d&oacute;nde ser&aacute;): JP INICIO_PROGRAMA.</li>
  <li>Cada procedimiento terminar&aacute; con un RET, para volver al 
punto desde el que se llam&oacute;, y tendr&aacute; una direcci&oacute;n
de comienzo, a la que llamaremos con un CALL. </li>
</ul>

<p>As&iacute;, el programa convertido a ensamblador tendr&iacute;a una apariencia
similar a:</p>

<pre><code>JP INICIO_PROGRAMA
INICIO_INICIALIZA
...
RET
INICIO_LINEA_HORIZONTAL
...
RET
INICIO_PROGRAMA
...
</code></pre>

<p><br />La situaci&oacute;n se complica si queremos permitir variables
locales y/o par&aacute;metros. No lo vamos a hacer todav&iacute;a, pero s&iacute; a
ver las nociones b&aacute;sicas, para aplicarlas m&aacute;s adelante:</p>

<ul>
  <li> El hecho de que haya variables locales, y de que alguna de ellas pueda llamarse igual que una variable global, se puede solucionar a&ntilde;adiendo informaci&oacute;n adicional en la tabla de s&iacute;mbolos: el &aacute;mbito al que pertenece una variable. Por ejemplo, para una variable "i" en el procedimiento "inicializa" podr&iacute;a haber otro campo que indique el procedimiento al que pertenece, o podr&iacute;amos simplemente cambiar su nombre por "i_inicializa" durante el an&aacute;lisis, pero eso fallar&iacute;a si el procedimiento (o funci&oacute;n) es recursivo. Tambi&eacute;n deber&iacute;amos plantearnos declarar la variable cuando se entra al procedimiento y eliminar la declaraci&oacute;n al salir de &eacute;l, para no desperdiciar espacio que quiz&aacute; no se est&eacute; usando.</li>
  <li>Sobre los par&aacute;metros, la forma habitual de trabajar es 
    preparar un &quot;registro de activaci&oacute;n&quot;, que contiene detalles sobre
    los par&aacute;metros, y quiz&aacute; incluso sobre datos locales e &quot;informaci&oacute;n
    administrativa&quot;, como la direcci&oacute;n a la que se debe volver
    cuando se termine de analizar el procedimiento. De momento todo
    ello son datos que nosotros no vamos a usar.</li>
</ul>

<p><br />De paso, aprovecharemos para hacer alguna peque&ntilde;a mejora:
que se puedan declarar varias variables del mismo tipo a la vez, algo
que todav&iacute;a no permit&iacute;a nuestro analizador:</p>

<pre><code>var
  i, j, k: byte;</code></pre>

  
<p><br />
  Como siempre, para m&aacute;s detalles, todo el c&oacute;digo est&aacute; en la p&aacute;gina del proyecto en Google Code:<br />
  <br />
  <a href="http://code.google.com/p/cpcpachi/">http://code.google.com/p/cpcpachi/</a></p>
<p align="right">(Volver al <a href="doc.html">&iacute;ndice</a>) </p>
</body>
</html>
